//============================================================================
// Name        : main.cpp
// Author      : Carlos Alegría
// Description : Programa para mostrar las características básicas de C++
//============================================================================

#include <iostream>
#include <string>

// la instrucción "using namespace" le dice al compilador que se utilizarán los
// miembros del namespace especificado, de forma que no es necesario utilizar
// con ellos el operador de resolución de alcance.
//
using namespace std;

/**
 * Suma uno a los argumentos.
 *
 * Esta función tiene como objetivo mostrar que las variables de referencia le
 * indican al compilador que los argumentos deben ser pasados por referencia a
 * la función.
 *
 * @param [in,out] p    Variable de referencia que será incrementada en uno.
 * @param [in,out] q    Variable de referencia que será incrementada en uno.
 */
void
modificar_por_referencia(int &p, int &q);

/**
 * Suma uno a los argumentos.
 *
 * Esta función tiene como objetivo mostrar que las variables que no son de
 * referencia son pasadas por valor, por lo que no pueden ser modificadas por
 * la función.
 *
 * @param [in] p    Variable que será incrementada en uno.
 * @param [in] q    Variable que será incrementada en uno.
 */
void
modificar_por_valor(int p, int q);

/**
 * Programa principal
 *
 * Muestra las características básicas de un programa escrito en C++:
 * <ul>
 * <li>Namespace <code>std</code></li>
 * <li>Stream <code>cout</code> para imprimir en la salida estándar</li>
 * <li>El tipo <code>string</code> de la biblioteca estándar de C++</li>
 * <li>El tipo <code>string</code> de la biblioteca estándar de C++</li>
 * <li>Variables de referencia</li>
 * </ul>
 */
int
main()
{

  // instanciación de un objeto del tipo string utilizando su constructor por
  // default
  //
  string cadena;

  // impresión de "!!!Hello World!!!" utilizando el operador "<<" para
  // direccionar una cadena al stream cout
  //
  cout << "!!!Hello World!!!" << std::endl;

  //
  // utilización de variables de referencia. p y q
  // son modificados por la función "modificar_por_referencia"
  //

  int p = 2;
  int q = 3;

  modificar_por_referencia(p, q);
  cout << "p = " << p << ", q =" << q << endl;

  modificar_por_valor(p, q);
  cout << "p = " << p << ", q =" << q << endl;

  return 0;
}

//
// Implementación de funciones
//

void
modificar_por_referencia(int &p, int &q)
{
  p += 1;
  q += 1;
}

void
modificar_por_valor(int p, int q)
{
  p += 1;
  q += 1;
}
